/*
 * $Id: HelloWorld.java 471756 2006-11-06 15:01:43Z husted $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.fwc.fw.action;

import com.fwc.fw.domo.AbstractPersistableDomo;
import com.fwc.fw.domo.Form;
import com.fwc.fw.domo.FormField;
import com.fwc.fw.service.DataStoreService;
import com.fwc.fw.util.FormFactory;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

/**
 * <code>Set welcome message.</code>
 */
@Results({
	  @Result(name="show", type="freemarker", location="ui/domo-show.ftl"),
	  @Result(name="edit", type="freemarker", location="ui/domo-show.ftl"),
	  @Result(name="create", type="freemarker", location="ui/domo-create.ftl"),
	  @Result(name="destroy", type="redirect", location="${controllerPath}"),
	  @Result(name="editNew", type="freemarker", location="ui/domo.ftl"),
	  @Result(name="index", type="freemarker", location="ui/domo.ftl"),
	  @Result(type="freemarker", location="ui/domo.ftl")
})
public class AbstractDomoMaintenanceController extends ControllerSupport {

	protected Class clazz = AbstractPersistableDomo.class;
	protected AbstractPersistableDomo domo;
	protected DataStoreService dss;

	public void setDataStoreService(DataStoreService dss) {
		this.dss = dss;
	}
	
	public Class getClazz() {
		return clazz;
	}

	public void setClazz(Class clazz) {
		this.clazz = clazz;
	}

	public List<AbstractPersistableDomo> getDomos() {
		List<AbstractPersistableDomo> domos = dss.findAll(clazz);
		return domos;
	}
	public List<AbstractPersistableDomo> getDomosFiltered() {
		List<AbstractPersistableDomo> domos = dss.findAll(clazz,true);
		return domos;
	}

	public List<AbstractPersistableDomo> findAll(Class clazz) {
		List<AbstractPersistableDomo> domos = dss.findAll(clazz);
		return domos;
	}

	public Collection<AbstractPersistableDomo> findAll(Class clazz, String q) {
		Collection<AbstractPersistableDomo> domos = dss.search(clazz, q);
		return domos;
	}

    public String create() throws Exception {
    	domo = dss.save(domo);
    	return "create";
    }
    
    public String update() throws Exception {
    	return create();
    }
        
    public String destroy() throws Exception {
    	dss.remove(domo);
    	return "destroy";
    }

    public void setId(String id) {
    	super.setId(id);
    	if(null!=id) {
    		try {
				domo = (AbstractPersistableDomo) dss.find(clazz,id);
			} catch (Exception e) {
				domo = null;
			}
    	}
    	if(null == domo) {
    		try {
				domo = (AbstractPersistableDomo) clazz.newInstance();
			} catch (InstantiationException e) {
			} catch (IllegalAccessException e) {
			}
    	}
    }

    /*
    public String getId() {
    	return domo.getKey();
    }
    */
    
    public AbstractPersistableDomo getModel() {
    	if(null == domo) {
    		try {
				domo = (AbstractPersistableDomo) clazz.newInstance();
			} catch (InstantiationException e) {
			} catch (IllegalAccessException e) {
			}
    	}
    	return domo;
    }

	public Form getForm(Class clazz) throws Exception {
		return FormFactory.getForm(clazz);
	}
	public Form getForm() throws Exception {
		return FormFactory.getForm(clazz);
	}
	public Collection<FormField> getFormFields(Class clazz) throws Exception {
		return FormFactory.getFormFields(clazz);
	}
	public Collection<FormField> getFormFields() throws Exception {
		return FormFactory.getFormFields(clazz);
	}
	
	public String getControllerPath() {
		String path = request.getServletPath().substring(1);
		if(path.contains("/")) {
			return "/"+path.substring(0,path.lastIndexOf('/'));
		} else {
			return "/"+path;
		}
	}
	
	public Map getRelated() {
		return new RelatedDomoFactory();
	}
	
	private class RelatedDomoFactory extends HashMap {
		public Object put(Object key, Object val) {
			Field f = null;
			try {
				f = getClazz().getDeclaredField((String) key);

				String id = "";
				if(null != val && ((String[]) val).length>0) id = ((String[]) val)[0];
				AbstractPersistableDomo subDomo;
				try {
					subDomo = dss.find(f.getType(), id);
				} catch (Exception e) {
					subDomo = null;
					e.printStackTrace();
				}

				AbstractPersistableDomo domo = getModel();
				BeanUtils.setProperty(domo, (String)key, subDomo);
				return subDomo;

			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				if(null!=f)
					try {
						f.set(domo, null);
					} catch (IllegalArgumentException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (IllegalAccessException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}
		public Object get(Object key) {
			String methName = "get"+((String) key).substring(0,1).toUpperCase() + ((String) key).substring(1);
			try {
				Object o = domo.getClass().getMethod(methName).invoke(domo);
				return o;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
			
		}
	}
	
}
